home *** CD-ROM | disk | FTP | other *** search
/ Floppyshop 2 / Floppyshop - 2.zip / Floppyshop - 2.iso / diskmags / 5791-.end / dmg-6143 / lza_rept / compres3.txt < prev    next >
Text File  |  1996-06-04  |  9KB  |  182 lines

  1.                Experiments in Data Compression III
  2.                     (or "The Path Not Taken")
  3.                          by John Kormylo
  4.                          E.L.F. Software
  5.  
  6.  
  7. State of the Art
  8.  
  9.      In the following table are shown the results for compressing 
  10. three  different  files using  three  different  methods.   'ZIP' 
  11. refers to STZIP 2.5 (deflating).  'LZA1' refers to the LZA method 
  12. used  by ELFBACK v2.9.   'LZA2' refers to the LZA method used  by 
  13. ELFARC v1.3.
  14.  
  15.  
  16.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  17. -------+--------------+-------------+--------------+
  18.    ZIP |       25134  |      32417  |      496876  |
  19.   LZA1 |       24860  |      34719  |      585185  |
  20.   LZA2 |       22029  |      31997  |      453143  |
  21. -------+--------------+-------------+--------------+
  22.  
  23. Back to Basics
  24.  
  25.      Huffman  and Arithmetic coding are fixed length to  variable 
  26. length codes.   They take advantage of the fact that some symbols 
  27. occur  more often than others,  and give them shorter codes  than 
  28. the  less  common symbols.   LZW is a variable  length  to  fixed 
  29. length code,  which attempts to create a dictionary of very  long 
  30. sequences  which  all have the same  probability  of  occurrence.  
  31. Whenever  a sequence is used,  the algorithm attempts to make  it 
  32. longer.
  33.      Previous  experience  indicates that a  variable  length  to 
  34. variable length code is best.   There are certain sequences which 
  35. occur relatively often,  but not necessarily together.   For text 
  36. this  should  be obvious in that words are used  many  times  but 
  37. usually in different combinations.  Therefore making the sequence 
  38. longer  is often not nearly as useful as reducing the  number  of 
  39. bits needed to code it.
  40.      LZA  codes  sequences  using a length  code  (based  on  the 
  41. relative  occurance  of matches of that length)  followed  by  an 
  42. alphabetical order code (based on how many matches of that length 
  43. were found in the dictionary).   Whether to use one long match or 
  44. two  short  matches was determined by calculating  the  resulting 
  45. number of bits for all possible combinations.   One would be hard 
  46. pressed to devise a more effective coding system.
  47.      The  problem with LZA is that it is slow.   In part this  is 
  48. due  to the binary tree search,  which must perform  many  string 
  49. comparisons to locate the first and last matches corresponding to 
  50. a specified length.   This is also due to the large dictionary of 
  51. possible sequences,  from which the best combination of sequences 
  52. must be determined.   There are 16K text pointers and 64 possible 
  53. lengths,  for  a  maximum  of  1  Meg  possible  strings  in  the 
  54. dictionary (only about half that number are unique).
  55.      A  smaller dictionary would require less time to search  and 
  56. might make the search for the best coding sequence unnecessary.
  57.  
  58.  
  59. Hash Tables
  60.  
  61.      Hash tables are faster than binary search trees.  Also, each 
  62. entry in the table corresponds to a particular length of  string, 
  63. and  is the only entry corresponding to that string.   Using  the 
  64. index of the dictionary entry corresponds to a variable to  fixed 
  65. length code (such as LZW).
  66.      For a variable to variable length code,  one would also need 
  67. to keep a count of how many times that string was used.   Because 
  68. of the 16 bit limit for the arithmetic coder, this means that the 
  69. total number of counts must be less than 64K.   Needless to  say, 
  70. the total number of strings in such a dictionary would have to be 
  71. much less than 1 Meg, probably less than 32K.
  72.  
  73.  
  74.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  75. -------+--------------+-------------+--------------+
  76.    LZW |       32341  |      45147  |      905744  |
  77.  Count |       31399  |      43143  |      771499  |
  78.  Prune |       30574  |      39608  |      647192  |
  79.  Merge |       28090  |      36325  |      606602  |
  80.  Smart |       25974  |      35426  |      567752  |
  81. -------+--------------+-------------+--------------+
  82.  
  83.      The above table shows the results for several LZ78 variants.  
  84. The  first uses LZW for all sequences and arithmetic  for  single 
  85. bytes.   The  second  keeps  track of the number  of  times  each 
  86. sequence is used (variable to variable length coding).   Both use 
  87. dictionaries with 8K entries.
  88.  
  89.      One of the problems with LZW is that once a string has  been 
  90. added to the dictionary,  it can never be removed.   Instead, the 
  91. entire  dictionary  is  thrown out  periodically  and  the  whole 
  92. process  begins again.   However,  it is possible to implement  a 
  93. hash table where entries can be removed.   Also,  one can set the 
  94. count  of  an entry to 0 so that intermediate strings  which  are 
  95. 'never'  used  will  not affect the coding  (although  they  will 
  96. continue to take up space in the hash table).
  97.      'Prune'  in  the above table reduces the  count  on  every 
  98. entry  whenever  the table is full (or the total  of  the  counts 
  99. reaches 64K).   By doing all of the entries at once, we avoid the 
  100. problem of having to re-sort.
  101.  
  102.     LZ78  and  LZW extend the strings in the  dictionary  by  one 
  103. character  each  time  they are  used.   This  has  two  problems 
  104. associated  with  it.   First,  the  strings  grow  very  slowly.  
  105. Second, in the process of adding a long string which is repeated 
  106. often,  one  will  also  form  lots of  short  strings  from  the 
  107. leftovers at all the intermediate stages.
  108.      A  much  more effective approach is to extend  a  string  by 
  109. every  character in the following string when two  strings  occur 
  110. concurently.   (Note,  this  means you cannot add strings to  the 
  111. dictionary  until  they  have been sent to  the  receiver.)   The 
  112. results for this method are shown as 'Merge' in the above table.
  113.  
  114.      It is not always best to choose the longest match available, 
  115. since  the  end  may  not line up  with  another  string  in  the 
  116. dictionary.   'Smart'  in the previous table shows  what  happens 
  117. when  you  choose  the match length in order  to  code  the  most 
  118. characters using two consecutive matches.   (Ties go to the match 
  119. with the highest count.)  The best news is that this approach  is 
  120. relatively fast.
  121.  
  122.  
  123. LZ79 (combining LZ77 & LZ78)
  124.  
  125.      It  was observed that tweaking the algorithm  produced  very 
  126. little change in the performance.  Also, the results were similar 
  127. to  the 'backwards matching' algorithm discussed in the  previous 
  128. chapter.   In  other words,  this is about as much as you can  do 
  129. with  dictionary compression.   The next logical thing to try  is 
  130. adding a 'FIFO buffer.'
  131.      A  64  byte sliding window was added to  the  match  search. 
  132. Lengths  2-64 were coded as 257-319 in the  arithmetic  character 
  133. set (256 is used for the hash table).   Offsets were sent without 
  134. weights.   'Long'  shows the results using the longer of the  two 
  135. matches  (with  ties  going  to the hash  table)  and  no  length 
  136. optimization  (compares to 'Merge' rather  than  'Smart').   This 
  137. achieved a minor improvement in the first two files,  and a major 
  138. improvement in WORDLIST.
  139.  
  140.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  141. -------+--------------+-------------+--------------+
  142.   Long |       28086  |      35397  |      522226  |
  143.   Ties |       28829  |      35880  |      493510  |
  144.   Best |       25785  |      34833  |      448995  |
  145.   Tree |       25498  |      34410  |      465510  |
  146.   Lags |       25397  |      34330  |      415494  |
  147.   16K  |       24489  |      34218  |      415349  |
  148. -------+--------------+-------------+--------------+
  149.  
  150.      'Ties' show the results of the above method when ties go  to 
  151. the sliding window instead of the hash table.   This demonstrates 
  152. the need for a more intelligent method for chosing which match to 
  153. use, since the results are highly data dependent.
  154.      'Best'  shows the results of using a Viterbi like  algorithm 
  155. to  determine  the  best match & length (the  same  one  used  in 
  156. 'LZA2').  This method looks at every possible way to compress the 
  157. next 64 bytes, at least until all paths have the same first step.  
  158. Of course, this approach is very slow even with the hash table.
  159.      'Tree'  uses a binary search tree together with  the  'Best' 
  160. algorithm.   Instead  of looking at the last  64  characters,  it 
  161. uses text pointers corresponding to the last 64 sequences coded.
  162.      'Lags'  uses counts of how often a match was found based  on 
  163. how  far  it  was  from  the  location  matched  (sort  of   like 
  164. autocorrelation data).   As shown in the appendix of the previous 
  165. report, these counts vary from file to file.
  166.      Experiments  with  the  buffer sizes  found  that  the  best 
  167. results  in  general were for a 64 entry FIFO buffer  and  a  16K 
  168. entry HASH table.  These results are shown as '16K.'
  169.      At  this point we are able to beat ZIP on two of  the  three 
  170. files.  Unfortunately, nothing seems to help the third file much.  
  171. Increasing  the  size of the FIFO buffer  helps  a  little.   The 
  172. problem  with this file is that it doesn't compress well at  all, 
  173. and the matches found tend to be very short.
  174.  
  175. Exhaustion
  176.  
  177.      Unfortunately,  I  was unable to find any way to  achieve  a 
  178. substantial  inprovement over the above  results.   However,  the 
  179. methods  developed during these experiments should be  applicable 
  180. to improving the speed using the old LZA algorithm.
  181.  
  182.